package com.roadjava.rbac.controller;

import com.alibaba.excel.EasyExcel;
import com.roadjava.rbac.bean.entity.Resource;
import com.roadjava.rbac.bean.req.resource.ResourcePageReq;
import com.roadjava.rbac.bean.res.Result;
import com.roadjava.rbac.es.PageResult;
import com.roadjava.rbac.es.RequestParams;
import com.roadjava.rbac.service.EsService;
import com.roadjava.rbac.service.ResourceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 资源控制器类
 * @author 怨九己
 */
@Slf4j
@RestController
@RequestMapping("/api/resources")
@RequiredArgsConstructor
public class ResourceController {
    private final ResourceService resourceService;

    private final EsService esService;

    /**
     * 根据 resourceId 查询资源
     * @param resourceId 资源ID
     * @return 资源对象
     */
    @GetMapping("/{resourceId}")
    public Result<Resource> getResourceById(@PathVariable Integer resourceId) {
        Resource resource = resourceService.findById(resourceId);
        return Result.buildSuccess(resource);
    }

    /**
     * 上传保存资源
     * @param resource 资源对象
     * @return 操作结果的描述信息
     */
    @PostMapping("")
    public Result<String> saveResource(@Valid @RequestBody Resource resource) {
        return resourceService.save(resource);
    }

    /**
     * 删除资源
     * @param resourceId 资源ID
     * @return 操作结果的描述信息
     */
    @DeleteMapping("")
    public Result<String> deleteResource(@RequestParam Integer resourceId) {
        return resourceService.delete(resourceId);
    }

    /**
     * 根据资源名称和标签搜索资源（支持分页）
     * @param resourceName 资源名称
     * @param tag 标签
     * @param pageNum 当前页码
     * @param pageSize 每页大小
     * @return 资源列表和总数
     */
    @GetMapping("")
    public Result<List<Resource>> searchResources(
            @RequestParam(required = false) String resourceName,
            @RequestParam(required = false) String tag,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize) {
        ResourcePageReq pageReq = new ResourcePageReq();
        pageReq.setPageNum(pageNum);
        pageReq.setPageSize(pageSize);
        return resourceService.searchResourcesByName(
                resourceName,
                tag,
                pageReq);
    }

    /**
    * 更新资源（只允许修改 resourceType, resourceDescription, 和 tag）
    * @param resourceId 资源ID
    * @param resourceUpdate 资源更新对象
    * @return 更新后的资源对象
    * */
    @PutMapping("/{resourceId}")
    public Result<Resource> updateResource(
            @Valid @PathVariable Integer resourceId,
            @RequestBody Resource resourceUpdate) {
            Resource updatedResource = resourceService.updateResource(
                    resourceId,
                    resourceUpdate);
            return Result.buildSuccess(updatedResource);
    }

    /**
     * 导出Excel
     * @param response 响应对象
     * @param resourceName 资源名称
     * @param tag 标签
     * @param pageNum 页码
     * @param pageSize 页大小
     * @throws IOException 异常
     */
    @GetMapping("/excel")
    public void exportExcel(
            HttpServletResponse response,
            @RequestParam(required = false) String resourceName,
            @RequestParam(required = false) String tag,
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize
    ) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType(
                "application/vnd" +
                ".openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("资源", "UTF-8")
                .replaceAll("\\+", "%20");
        response.setHeader("Content-disposition",
                "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //查询数据
        ResourcePageReq pageReq = new ResourcePageReq();
        pageReq.setPageNum(pageNum);
        pageReq.setPageSize(pageSize);
        List<Resource> data =
                resourceService
                        .searchResourcesByName(resourceName, tag,pageReq)
                        .getData();
        EasyExcel
                .write(response.getOutputStream(), Resource.class)
                .sheet("模板")
                .doWrite(data);
    }

    @PostMapping("/es")
    public PageResult search(@RequestBody RequestParams params) {
        return esService.search(params);
    }

}

